home *** CD-ROM | disk | FTP | other *** search
- #include "MenuPet.h"
- #include <AppleEvents.h>
- #include <stdlib.h>
- #include <Icons.h>
- #include "LayerMgr.h"
- /*
- Any parts written by me are Copyright 1995 Christopher Evans
- All Rights Reserved.
- */
-
- /*******************************************************************************
-
- The “g” prefix is used to emphasize that a variable is global.
-
- *******************************************************************************/
-
- SysEnvRec gMac;
- Boolean gQuit;
- Boolean gInBackground;
-
- WindowPtr GetDesktopWindow(void);
-
- Point lastPosition = {20,20};
- Point destination = {120,15};
-
- Rect appleRect = {5, 15, 16, 30};
-
- RGBColor rgbBlack = {0,0,0};
- RGBColor rgbWhite = {65535,65535, 65535};
-
- unsigned long goHUntil = 0;
- unsigned long goVUntil = 0;
- unsigned long lastSleepTime = 0;
- unsigned long nextMoveTime = 0;
- Boolean gStuck = false;
- short stuckCount = 0;
-
- #define MAX_STUCK_COUNT 60
- //#define BOTTOM_BOUNDS (GetMBarHeight() - 4)
- #define BOTTOM_BOUNDS (wmPort->portRect.bottom)
- #define MAX_REST 600 //In ticks
- #define PET_LAZINESS -1
-
- //#define LARGE_BUG 1
-
- GrafPtr petPort;
- RgnHandle petRgnUp = nil;
- Handle petSuiteUp = nil;
- RgnHandle petRgnRt = nil;
- Handle petSuiteRt = nil;
- RgnHandle petRgnDn = nil;
- Handle petSuiteDn = nil;
- RgnHandle petRgnLt = nil;
- Handle petSuiteLt = nil;
-
- short lastDirection = 0;
-
- enum {
- dirUp = 1,
- dirRight,
- dirDown,
- dirLeft
- };
- /*******************************************************************************
-
- Define HiWrd and LoWrd macros for efficiency.
-
- *******************************************************************************/
-
- #define HiWrd(aLong) (((aLong) >> 16) & 0xFFFF)
- #define LoWrd(aLong) ((aLong) & 0xFFFF)
- //#define abs(x) ((x < 0) ? -(x) : x)
-
- void InitToolbox(void);
- void MainEventLoop(void);
- void DeathAlert(short errNumber);
- void HandleEvent(EventRecord *event);
- Boolean TrapExists(short theTrap);
- TrapType GetTrapType(short theTrap);
- short NumToolboxTraps(void);
- void CleanUp(void);
- void MoveMyPet(void);
- void HandleMouseDown(EventRecord *event);
- void HandleMenuCommand(long menuResult);
- void HandleKeyPress(EventRecord *event);
- void AdjustMenus(void);
- Boolean PtNearPet(Point pt);
-
- /*******************************************************************************
-
- main
-
- Entry point for our program. We initialize the toolbox, make sure we are
- running on a sufficiently studly machine, and put up the menubar. Finally,
- we start polling for events and handling them by entering our main event
- loop.
-
- *******************************************************************************/
- main()
- {
- GrafPtr savePort;
- /* If you have stack requirements that differ from the default,
- then you could use SetApplLimit to increase StackSpace at
- this point, before calling MaxApplZone. */
-
- MaxApplZone(); /* Expand the heap so code segments load
- at the top */
- InitToolbox(); /* Initialize the program */
-
- {
- #ifdef LARGE_BUG
- Rect iconRect = {0,0,32,32};
- GetIconSuite(&petSuiteUp, 1, svAllLargeData);
- GetIconSuite(&petSuiteRt, 2, svAllLargeData);
- GetIconSuite(&petSuiteDn, 3, svAllLargeData);
- GetIconSuite(&petSuiteLt, 4, svAllLargeData);
-
- #else
- Rect iconRect = {0,0,16,16};
- GetIconSuite(&petSuiteUp, 1, svAllAvailableData);
- GetIconSuite(&petSuiteRt, 2, svAllAvailableData);
- GetIconSuite(&petSuiteDn, 3, svAllAvailableData);
- GetIconSuite(&petSuiteLt, 4, svAllAvailableData);
- #endif
- petRgnUp = NewRgn();
- IconIDToRgn(petRgnUp, &iconRect, atBottom + atHorizontalCenter, 1);
- petRgnRt = NewRgn();
- IconIDToRgn(petRgnRt, &iconRect, atBottom + atHorizontalCenter, 2);
- petRgnDn = NewRgn();
- IconIDToRgn(petRgnDn, &iconRect, atBottom + atHorizontalCenter, 3);
- petRgnLt = NewRgn();
- IconIDToRgn(petRgnLt, &iconRect, atBottom + atHorizontalCenter, 4);
- }
-
- GetPort(&savePort);
- petPort = GetDesktopWindow();
- MainEventLoop(); /* Call the main event loop */
- SetPort(savePort);
- }
-
-
- /*******************************************************************************
-
- InitToolbox
-
- Set up the whole world, including global variables, Toolbox managers, and
- menus.
-
- *******************************************************************************/
- void InitToolbox()
- {
- Handle menuBar;
- EventRecord event;
- short count;
- long gestaltResponse;
- OSErr myErr;
-
- gInBackground = FALSE;
- gQuit = FALSE;
-
- InitGraf((Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(NIL);
- InitCursor();
-
- MoreMasters();
- MoreMasters();
-
- GetDateTime((unsigned long *)&qd.randSeed); //Initialize the random number generator
-
- /* This next bit of code waits until MultiFinder brings our application
- to the front. This gives us a better effect if we open a window at
- startup. */
-
- // for (count = 1; count <= 3; ++count)
- // EventAvail(everyEvent, &event);
-
- SysEnvirons(curSysEnvVers, &gMac);
-
- if (gMac.machineType < 0)
- DeathAlert(errWimpyROMs);
-
- if (gMac.systemVersion < 0x0600)
- DeathAlert(errWimpySystem);
-
- if (!TrapExists(_WaitNextEvent))
- DeathAlert(errWeirdSystem);
-
-
- menuBar = GetNewMBar(rMenuBar); /* Read menus into menu bar */
- if ( menuBar == NIL )
- DeathAlert(errNoMenuBar);
- SetMenuBar(menuBar); /* Install menus */
- DisposHandle(menuBar);
- AddResMenu(GetMHandle(mApple), 'DRVR'); /* Add DA names to Apple menu */
- DrawMenuBar();
- }
-
-
- void DeathAlert(short errNumber)
- {
- short itemHit;
- Str255 theMessage;
-
- SetCursor(&qd.arrow);
- GetIndString(theMessage, rErrorStrings, errNumber);
- ParamText(theMessage, NIL, NIL, NIL);
- itemHit = StopAlert(rErrorAlert, NIL);
- ExitToShell();
- }
-
-
-
-
- /*******************************************************************************
-
- MainEventLoop
-
- Get events forever, and handle them by calling HandleEvent. First, call
- DoAdjustCursor to set our cursor shape, and to set the cursor region. We
- then call WaitNextEvent() to get the event. This is OK, because we know
- we’re running on System 6.0 or later by this time. If we got an event, we
- handle it by calling HandleEvent(). But before doing that, we call
- DoAdjustCursor again in case our application had fallen asleep under
- MultiFinder.
-
- *******************************************************************************/
- void MainEventLoop()
- {
- RgnHandle cursorRgn;
- Boolean gotEvent;
- EventRecord event;
- Point mouse;
- long lastFlagsCheck = 0, checkInterval;
-
- cursorRgn = NIL;
- while ( !gQuit ) {
-
- gotEvent = WaitNextEvent(everyEvent, &event, (gInBackground?2:1), nil);
- if ( gotEvent ) {
- HandleEvent(&event);
- MoveMyPet();
- }
- else{
- MoveMyPet();
- }
- }
- CleanUp();
- }
-
-
- /*******************************************************************************
-
- HandleEvent
-
- Do the right thing for an event. Determine what kind of event it is, and
- call the appropriate routines.
-
- *******************************************************************************/
- void HandleEvent(EventRecord *event)
- {
- switch ( event->what ) {
- case mouseDown:
- HandleMouseDown(event);
- break;
- case keyDown:
- case autoKey:
- HandleKeyPress(event);
- break;
- case activateEvt:
- // HandleActivate(event);
- break;
- case updateEvt:
- // HandleUpdate(event);
- break;
- case diskEvt:
- // HandleDiskInsert(event);
- break;
- case osEvt:
- // HandleOSEvent(event);
- break;
- case kHighLevelEvent:
- // AEProcessAppleEvent(event);
- break;
- default:
- break;
- }
- }
-
- Boolean TrapExists(short theTrap)
- {
- TrapType theTrapType;
-
- theTrapType = GetTrapType(theTrap);
- if ((theTrapType == ToolTrap) && ((theTrap &= 0x07FF) >= NumToolboxTraps()))
- return false;
- else
- return (NGetTrapAddress(_Unimplemented, ToolTrap) !=
- NGetTrapAddress(theTrap, theTrapType));
- }
-
-
- /*******************************************************************************
-
- GetTrapType
-
- Check the bits of a trap number to determine its type. If bit 11 is set,
- it’s a toolbox trap. Otherwise, it’s an OS trap.
-
- *******************************************************************************/
- TrapType GetTrapType(short theTrap)
- {
- if ((theTrap & 0x0800) == 0) /* Per D.A. */
- return (OSTrap);
- else
- return (ToolTrap);
- }
-
-
- /*******************************************************************************
-
- NumToolboxTraps
-
- Find the size of the Toolbox trap table. This can be either 0x0200 or
- 0x0400 bytes, depending on which Macintosh we are running on. We determine
- the size by taking advantage of an anomaly of the smaller trap table: any
- entries that fall beyond the end of the table are mirrored back down into
- the lower part. For example, on a large table, trap numbers A86E and AA6E
- correspond to different routines. However, on a small table, they
- correspond to the same routine. By checking the addresses of these
- routines, we can determine the size of the table.
-
- *******************************************************************************/
- short NumToolboxTraps(void)
- {
- if (NGetTrapAddress(0xA86E, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
- return (0x200);
- else
- return (0x400);
- }
-
-
- void CleanUp(void)
- {
-
- }
-
- void HandleMouseDown(EventRecord *event)
- {
- long newSize;
- Rect growRect;
- WindowPtr theWindow;
- short part = FindWindow(event->where, &theWindow);
- GrafPtr savePort;
-
- switch ( part ) {
- case inMenuBar: /* Process a mouse menu command (if any) */
- AdjustMenus();
- HandleMenuCommand(MenuSelect(event->where));
- // if(PtInRgn(event->where,petRgn)) {
- // SysBeep(10);
- // }
- break;
- case inSysWindow: /* Let the system handle the mouseDown */
- SystemClick(event, theWindow);
- break;
- case inContent:
- break;
-
- case inDrag: /* Pass screenBits.bounds to get all gDevices */
- break;
-
- case inGrow:
- break;
- case inGoAway:
- break;
- case inZoomIn:
- case inZoomOut:
- break;
- }
- }
-
-
- void HandleMenuCommand(menuResult)
- long menuResult;
- {
- short menuID; /* The resource ID of the selected menu */
- short menuItem; /* The item number of the selected menu */
- Str255 daName;
- WindowPtr window;
- MenuHandle menu;
- ModalFilterUPP aboutFilter;
-
- menuID = HiWrd(menuResult);
- menuItem = LoWrd(menuResult);
- switch ( menuID ) {
- case mApple:
- switch ( menuItem ) {
- case iAbout:
- break;
- default: /* All non-About items in this menu are DAs */
- GetItem(GetMHandle(mApple), menuItem, daName);
- (void) OpenDeskAcc(daName);
- break;
- }
- break;
- case mFile:
- switch ( menuItem ) {
- case iNew:
- /* DoNewWindow(); */
- AdjustMenus();
- DrawMenuBar();
- break;
- case iOpen:
- break;
- case iClose:
- break;
-
- case iSave:
- break;
-
- case iSaveAs:
- break;
-
- case iQuit:
- gQuit = TRUE;
- break;
- }
- break;
- case mEdit:
- switch (menuItem) {
- /* Call SystemEdit for DA editing & MultiFinder */
- /* since we don’t do any Editing */
- case iUndo:
- case iCut:
- case iCopy:
- case iPaste:
- break;
- }
- }
- HiliteMenu(0); /* Unhighlight what MenuSelect or MenuKey hilited */
- }
-
- /*******************************************************************************
-
- HandleKeyPress
-
- The user pressed a key. What are you going to do about it?
-
- *******************************************************************************/
- void HandleKeyPress(EventRecord *event)
- {
- char key;
-
- key = event->message & charCodeMask;
- if ( event->modifiers & cmdKey ) { /* Command key down? */
- AdjustMenus(); /* Enable/disable/check menu items properly */
- HandleMenuCommand(MenuKey(key));
- } else {
- if(key == '?') {
- GrafPtr wmPort, savePort;
- RgnHandle showRgn = NewRgn();
- Rect showRect;
- long junkLong;
-
- GetPort(&savePort);
- // GetWMgrPort(&wmPort);
- wmPort = (GrafPtr)petPort;
- SetPort(wmPort);
-
- switch(lastDirection) {
- case dirUp:
- CopyRgn(petRgnUp, showRgn);
- break;
- case dirLeft:
- CopyRgn(petRgnLt, showRgn);
- break;
- case dirDown:
- CopyRgn(petRgnDn, showRgn);
- break;
- case dirRight:
- CopyRgn(petRgnRt, showRgn);
- break;
- default:
- CopyRgn(petRgnUp, showRgn);
- }
- OffsetRgn(showRgn,lastPosition.h,lastPosition.v);
-
- InsetRgn(showRgn,-1,-1);
- InvertRgn(showRgn);
- Delay(5, &junkLong ); //OSUtils.h
- InvertRgn(showRgn);
- Delay(5, &junkLong ); //OSUtils.h
- InvertRgn(showRgn);
- Delay(5, &junkLong ); //OSUtils.h
- InvertRgn(showRgn);
- SetPort(savePort);
- DisposeRgn(showRgn);
- }
- if(key == 'z') {
- GrafPtr wmPort, savePort;
- GetPort(&savePort);
- // GetCWMgrPort((CGrafPtr *)&wmPort);
- wmPort = (GrafPtr)petPort;
- SetPort(wmPort);
- InvalRect(&wmPort->portRect);
-
- SetPort(savePort);
- }
- /* DoKeyPress(event) */;
- }
- }
-
- void AdjustMenus()
- {
-
- }
-
- Boolean PtNearPet(Point pt)
- {
- Rect showRect;
- Boolean result;
-
- SetRect(&showRect, lastPosition.h, lastPosition.v, lastPosition.h+4, lastPosition.v+4);
-
- InsetRect(&showRect, -20 , -20);
-
- result = PtInRect(pt, &showRect);
-
- return result;
- }
-
-
-
-
- void MoveMyPet(void)
- {
- GrafPtr savePort, wmPort;
- RgnHandle oldPetRgn, newPetRgn, updateRgn;
- Boolean goH = false, goV = false;
- Point mouseLoc;
- unsigned long curTick = TickCount();
- Point oldPosition = lastPosition;
- OSErr theErr;
- #ifdef LARGE_BUG
- Rect iconRect = {0,0,32,32};
- #else
- Rect iconRect = {0,0,16,16};
- #endif
-
- if(PET_LAZINESS > 0) {
- if(curTick % PET_LAZINESS != 0) {
- return;
- }
- }
-
-
- GetPort(&savePort);
- // GetWMgrPort(&wmPort);
- GetCWMgrPort((CGrafPtr *)&wmPort);
- wmPort = (GrafPtr)petPort;
-
- SetPort(wmPort);
- if(curTick < nextMoveTime) {
-
- OffsetRect(&iconRect,lastPosition.h,lastPosition.v);
- switch(lastDirection) {
- case dirUp:
- theErr = PlotIconSuite(&iconRect, atBottom + atHorizontalCenter, ttDisabled, petSuiteUp);
- break;
- case dirLeft:
- theErr = PlotIconSuite(&iconRect, atBottom + atHorizontalCenter, ttDisabled, petSuiteLt);
- break;
- case dirDown:
- theErr = PlotIconSuite(&iconRect, atBottom + atHorizontalCenter, ttDisabled, petSuiteDn);
- break;
- case dirRight:
- theErr = PlotIconSuite(&iconRect, atBottom + atHorizontalCenter, ttDisabled, petSuiteRt);
- break;
- default:
- theErr = PlotIconSuite(&iconRect, atBottom + atHorizontalCenter, ttDisabled, petSuiteUp);
- }
- SetPort(savePort);
- return;
- }
-
- GetMouse(&mouseLoc);
-
- RGBForeColor(&rgbWhite);
-
-
- if(goHUntil > curTick) {
- goH = true;
- }
- else {
- if(Random() %5 == 0) {
- goHUntil = curTick + (60 * (abs(Random()) % 5));
- }
- }
-
- if(goVUntil > curTick) {
- goV = true;
- }
- else {
- if(Random() %10 == 0) {
- goVUntil = curTick + (60 * (abs(Random()) % 3));
- }
- }
-
- if(mouseLoc.v < GetMBarHeight()) {
- goH = true;
- }
-
- if(goH) {
- if(PtNearPet(mouseLoc) ){
- if( lastPosition.h > mouseLoc.h ) {
- lastPosition.h += 2;
- if(lastPosition.h > wmPort->portRect.right) {
- lastPosition.h -= 2;
- }
- }
- else {
- lastPosition.h -= 2;
- if(lastPosition.h < wmPort->portRect.left) {
- lastPosition.h += 2;
- }
- }
-
- }
- else {
- if(destination.h > lastPosition.h) {
- lastPosition.h ++;
- if(lastPosition.h > wmPort->portRect.right) {
- lastPosition.h -= 1;
- }
- }
- if(destination.h < lastPosition.h) {
- lastPosition.h -= 1;
- if(lastPosition.h < wmPort->portRect.left) {
- lastPosition.h += 1;
- }
- }
- }
- }
-
- if((destination.h == lastPosition.h && destination.v == lastPosition.v) || stuckCount == MAX_STUCK_COUNT){
- if(stuckCount != MAX_STUCK_COUNT) {
- nextMoveTime = lastSleepTime = curTick + (abs(Random()) % MAX_REST);
- }
- // else {
- // DebugStr("\presetting 'cuz stuck");
- // }
- destination.h = wmPort->portRect.left + abs(Random() % (wmPort->portRect.right - wmPort->portRect.left));
- destination.v = wmPort->portRect.top + abs(Random() % (wmPort->portRect.bottom - wmPort->portRect.top));
- {
- long longPt = PinRect(&petPort->portRect, destination); /* IM I pg 293 */
- destination = *((Point *)&longPt);
- }
- stuckCount = 0; //when we decide to go somewhere else, reset the stuck count in case we were stuck.
- }
-
- if(goV) {
- if(destination.v > lastPosition.v) {
- lastPosition.v ++;
- if(lastPosition.v > BOTTOM_BOUNDS) {
- lastPosition.v --;
- }
- }
- else {
- if(destination.v < lastPosition.v) {
- lastPosition.v --;
- if(lastPosition.v < 0) {
- lastPosition.v ++;
- }
- }
- }
- }
-
- if(gStuck) {
-
- if(destination.v < lastPosition.v) {
- destination.v++;
- }
- else {
- destination.v --;
- }
- if(destination.h < lastPosition.h) {
- destination.h++;
- }
- else {
- destination.h --;
- }
- // stuckCount ++;
- }
-
- {
- long longPt = PinRect(&petPort->portRect, lastPosition); /* IM I pg 293 */
- Point tmpPosition;
- tmpPosition.h += 8;
- tmpPosition.v += 8;
-
- lastPosition = *((Point *)&longPt);
- tmpPosition = lastPosition;
- //if(!PtInRgn(tmpPosition, petPort->visRgn)) {
- // lastPosition = oldPosition;
- // if(!gStuck) stuckCount = 0;
- // gStuck = true;
- //}
- //else {
- // gStuck = false;
- //}
- }
-
- RGBForeColor(&rgbBlack);
-
- oldPetRgn = NewRgn();
- newPetRgn = NewRgn();
- updateRgn = NewRgn();
-
- switch(lastDirection) {
- case dirUp:
- CopyRgn(petRgnUp, oldPetRgn);
- break;
- case dirLeft:
- CopyRgn(petRgnLt, oldPetRgn);
- break;
- case dirDown:
- CopyRgn(petRgnDn, oldPetRgn);
- break;
- case dirRight:
- CopyRgn(petRgnRt, oldPetRgn);
- break;
- default:
- CopyRgn(petRgnUp, oldPetRgn);
- }
- OffsetRgn(oldPetRgn,oldPosition.h,oldPosition.v);
-
- if(oldPosition.h > lastPosition.h) { //Going left
- if(oldPosition.v > lastPosition.v) { //Going up
- lastDirection = dirLeft;
- }
- else { //Going down
- lastDirection = dirDown;
- }
- }
- else { //Going right
- if(oldPosition.v > lastPosition.v) { //Going up
- lastDirection = dirUp;
- }
- else { //Goung down
- lastDirection = dirRight;
- }
- }
-
- switch(lastDirection) {
- case dirUp:
- CopyRgn(petRgnUp, newPetRgn);
- break;
- case dirLeft:
- CopyRgn(petRgnLt, newPetRgn);
- break;
- case dirDown:
- CopyRgn(petRgnDn, newPetRgn);
- break;
- case dirRight:
- CopyRgn(petRgnRt, newPetRgn);
- break;
- default:
- CopyRgn(petRgnUp, newPetRgn);
- }
- OffsetRgn(newPetRgn,lastPosition.h,lastPosition.v);
-
- DiffRgn(oldPetRgn, newPetRgn, updateRgn);
- // EraseRgn(updateRgn);
- InvalRgn(updateRgn);
-
- OffsetRect(&iconRect,lastPosition.h,lastPosition.v);
- switch(lastDirection) {
- case dirUp:
- theErr = PlotIconSuite(&iconRect, atBottom + atHorizontalCenter, ttNone, petSuiteUp);
- break;
- case dirLeft:
- theErr = PlotIconSuite(&iconRect, atBottom + atHorizontalCenter, ttNone, petSuiteLt);
- break;
- case dirDown:
- theErr = PlotIconSuite(&iconRect, atBottom + atHorizontalCenter, ttNone, petSuiteDn);
- break;
- case dirRight:
- theErr = PlotIconSuite(&iconRect, atBottom + atHorizontalCenter, ttNone, petSuiteRt);
- break;
- default:
- theErr = PlotIconSuite(&iconRect, atBottom + atHorizontalCenter, ttNone, petSuiteUp);
- }
- LMSetPaintWhite(TRUE); //Lowmem.h
- LMSetSaveUpdate(TRUE);
- PaintOne((WindowRef)petPort, updateRgn);
- PaintBehind((WindowRef)petPort, updateRgn);
-
-
- DisposeRgn(oldPetRgn);
- DisposeRgn(newPetRgn);
- DisposeRgn(updateRgn);
- // InvertRgn(petRgn);
-
- SetPort(savePort);
- }
-
- WindowPtr GetDesktopWindow(void)
- {
- WindowPtr desktopWindow;
- Str255 wTitle;
-
- desktopWindow = GetFrontWindowForSignature('FNDR');
- if(desktopWindow) {
- while( desktopWindow ) {
- GetWTitle(desktopWindow, wTitle);
- if(RelString(wTitle, "\pDesktop", true, true) == 0) { /* IM IV pg 234 */
- return desktopWindow;
- }
- desktopWindow = (WindowPtr)((WindowPeek)desktopWindow)->nextWindow;
- }
- }
- return nil;
-
- }
-
-
-
-